"""
合约配置文件适配器

提供从配置文件读取合约信息的功能，接口与services.contract_service保持一致
"""

import logging
import importlib.util
from pathlib import Path
from typing import Dict, Any, Optional
from services.exchange.interface import ExchangeType

logger = logging.getLogger(__name__)

def _load_config_module():
    """
    动态加载配置模块
    
    返回:
        配置模块，如果加载失败则返回None
    """
    # 配置文件路径
    project_root = Path(__file__).parent.parent
    config_path = project_root / "config" / "contracts_config.py"
    
    if not config_path.exists():
        logger.warning(f"合约配置文件不存在: {config_path}")
        return None
    
    try:
        # 动态加载配置模块
        spec = importlib.util.spec_from_file_location("contracts_config", config_path)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        return module
    except Exception as e:
        logger.error(f"加载合约配置文件失败: {e}")
        return None

# 加载配置模块
_config_module = _load_config_module()

def get_contract_info(exchange: ExchangeType, symbol: str) -> Optional[Dict[str, Any]]:
    """
    获取合约信息
    
    参数:
        exchange: 交易所类型
        symbol: 合约符号
        
    返回:
        合约信息字典，如果合约不存在或配置文件未加载则返回None
    """
    if _config_module is None:
        logger.warning("合约配置模块未加载，无法获取合约信息")
        return None
    
    exchange_name = exchange.name if isinstance(exchange, ExchangeType) else exchange
    
    try:
        return _config_module.get_contract_info(exchange_name, symbol)
    except Exception as e:
        logger.error(f"从配置文件获取合约信息失败: {e}")
        return None

def get_mark_price_round(exchange: ExchangeType, symbol: str) -> Optional[float]:
    """
    获取合约标记价格精度
    
    参数:
        exchange: 交易所类型
        symbol: 合约符号
        
    返回:
        标记价格精度，如果合约不存在或配置文件未加载则返回None
    """
    if _config_module is None:
        logger.warning("合约配置模块未加载，无法获取价格精度")
        return None
    
    exchange_name = exchange.name if isinstance(exchange, ExchangeType) else exchange
    
    try:
        return _config_module.get_mark_price_round(exchange_name, symbol)
    except Exception as e:
        logger.error(f"从配置文件获取价格精度失败: {e}")
        return None

def get_quanto_multiplier(exchange: ExchangeType, symbol: str) -> Optional[float]:
    """
    获取合约乘数
    
    参数:
        exchange: 交易所类型
        symbol: 合约符号
        
    返回:
        合约乘数，如果合约不存在或配置文件未加载则返回None
    """
    if _config_module is None:
        logger.warning("合约配置模块未加载，无法获取合约乘数")
        return None
    
    exchange_name = exchange.name if isinstance(exchange, ExchangeType) else exchange
    
    try:
        return _config_module.get_quanto_multiplier(exchange_name, symbol)
    except Exception as e:
        logger.error(f"从配置文件获取合约乘数失败: {e}")
        return None

def get_all_symbols(exchange: Optional[ExchangeType] = None) -> list:
    """
    获取所有合约符号列表
    
    参数:
        exchange: 可选，指定交易所类型进行过滤
        
    返回:
        合约符号列表
    """
    if _config_module is None:
        logger.warning("合约配置模块未加载，无法获取合约符号列表")
        return []
    
    exchange_name = exchange.name if isinstance(exchange, ExchangeType) else exchange
    
    try:
        return _config_module.get_all_symbols(exchange_name)
    except Exception as e:
        logger.error(f"从配置文件获取合约符号列表失败: {e}")
        return []

def format_price(exchange: ExchangeType, symbol: str, price: float) -> float:
    """
    根据合约标记价格精度格式化价格
    
    参数:
        exchange: 交易所类型
        symbol: 合约符号
        price: 原始价格
        
    返回:
        格式化后的价格，根据合约的mark_price_round保留相应小数位
    """
    mark_price_round = get_mark_price_round(exchange, symbol)
    
    # 如果获取不到合约信息或标记价格精度，返回原价格
    if mark_price_round is None:
        return price
        
    try:
        # 将字符串转换为浮点数
        round_value = float(mark_price_round)
        
        # 根据round_value计算小数位数
        if round_value == 0.01:
            return round(price, 2)  # 保留2位小数
        elif round_value == 0.001:
            return round(price, 3)  # 保留3位小数
        elif round_value == 0.0001:
            return round(price, 4)  # 保留4位小数
        elif round_value == 0.00001:
            return round(price, 5)  # 保留5位小数
        elif round_value == 0.000001:
            return round(price, 6)  # 保留6位小数
        elif round_value == 0.0000001:
            return round(price, 7)  # 保留7位小数
        elif round_value == 0.00000001:
            return round(price, 8)  # 保留8位小数
        else:
            # 通用方法：计算小数位数
            if round_value > 0:
                decimal_places = 0
                temp = round_value
                while temp < 1:
                    temp *= 10
                    decimal_places += 1
                return round(price, decimal_places)
            return price
            
    except (ValueError, TypeError) as e:
        logger.warning(f"格式化价格时出错: {e}, 合约: {symbol}, 标记价格精度: {mark_price_round}")
        return price 